<?php

namespace App\Http\Controllers\Api\V1;

use App\Enums\ResponseCode;
use App\Enums\SmsEnum;
use App\Exceptions\ApiExceptions;
use App\Exceptions\BusinessException;
use App\Http\Controllers\Api\AbstractApiController;
use App\Http\Resources\UserInfo;
use App\Http\Resources\UserResumeInfo;
use App\Models\User;
use App\Services\Easemob\EasemobService;
use App\Services\Im\WechatService;
use App\Services\Sms\SmsService;
use App\Services\User\EducationService;
use App\Services\User\UserService;
use App\Services\User\WorkExperienceService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use App\Services\Umeng\UmengService;
use Illuminate\Support\Facades\Cache;
use PHPOpenSourceSaver\JWTAuth\Exceptions\JWTException;

class UserController extends AbstractApiController
{
    /**
     * @param Request $request
     * @return JsonResponse
     */
    public function updateResume(Request $request): JsonResponse
    {
        $input = $request->validate([
            'name' => 'required|max:5',
            'gender' => 'required|in:' . implode(',', array_keys(User::GENDER_LIST)),
            'birthday' => 'required|date',
            'identity' => 'in:' . implode(',', array_keys(User::IDENTITY_LIST)),
        ]);
        UserService::editPayProfile(auth('api')->id(), $input);
        
        return $this->success(trans("修改个人简历成功"));
    }

    /**
     * 个人简历信息
     * @return JsonResponse
     */
    public function resumeInfo(): JsonResponse
    {
        $info = auth('api')->user();
        return self::success(trans("success"), ResponseCode::OK, new UserResumeInfo($info));
    }
    /**
     * 修改个人描述
     * @param Request $request
     * @return JsonResponse
     */
    public function updateDescription(Request $request): JsonResponse
    {
        $input = $request->validate([
            'description' => 'required|max:150',
        ]);
        UserService::editPayProfile(auth('api')->id(), [
            'self_description' => $input['description'],
        ]);
        return $this->success(trans("修改个人描述成功"));
    }

    /**
     * 修改手机号
     * @param Request $request
     * @return JsonResponse
     * @throws BusinessException
     */
    public function editMobile(Request $request): JsonResponse
    {
        $input = $request->validate([
            'mobile' => 'required',
            'verify_code' => 'required',
        ]);

        SmsService::verify($input['mobile'], $input['verify_code'], SmsEnum::CHANGE_MOBILE_OLD);
        //验证安全密码
        UserService::editPayProfile(auth('api')->id(), ['mobile' => $input['mobile']]);
        return self::success(trans("绑定手机号码成功"));
    }

    /**
     * 修改教育经历
     * @param Request $request
     * @param EducationService $service
     * @return JsonResponse
     * @throws ApiExceptions
     */
    public function updateEducation(Request $request, EducationService $service): JsonResponse
    {
        $input = $request->validate([
            'school_name' => 'required:max:20',
            'degree' => 'required|max:10',
            'graduation_date' => 'required|date',
            'major' => 'max:20',
        ]);
        $service->update(
            uid: auth('api')->id(),
            name: $input['school_name'],
            degree: $input['degree'],
            graduation_date: $input['graduation_date'],
            major: $input['major']??'',
        );
        return self::success(trans("修改教育经历成功"));
    }

    //添加工作经历
    public function addWorkExperience(Request $request,WorkExperienceService $service){
        $input = $request->validate([
            'company_name' => 'required:max:20',
            'start_date' => 'required|date',
            'end_date' => 'required|date',
            'job_description' => 'required:max:150',
        ]);
        $service->create(
            uid: auth('api')->id(),
            company_name: $input['company_name'],
            start_date: $input['start_date'],
            end_date: $input['end_date'],
            job_description: $input['job_description'],
        );
        return self::success(trans("添加工作经历成功"));
    }


    /**
     * 修改工作经历
     * @param Request $request
     * @param WorkExperienceService $service
     * @return JsonResponse
     * @throws ApiExceptions
     */
    public function updateWorkExperience(Request $request,WorkExperienceService $service): JsonResponse
    {
        $input = $request->validate([
            'company_name' => 'required:max:20',
            'start_date' => 'required|date',
            'end_date' => 'required|date',
            'job_description' => 'required:max:150',
            'work_experience_id' => 'required'
        ]);
        $service->update(
            uid: auth('api')->id(),
            work_experience_id: $input['work_experience_id'],
            company_name: $input['company_name'],
            start_date: $input['start_date'],
            end_date: $input['end_date'],
            job_description: $input['job_description'],
        );
        return self::success(trans("修改工作经历成功"));
    }


    //删除工作经历
    public function delWorkExperience(Request $request,WorkExperienceService $service)
    {
        $input = $request->validate([
            'work_experience_id' => 'required'
        ]);
        $service->delete(
            work_experience_id: $input['work_experience_id'],
            uid: auth('api')->id(),
        );
        return self::success(trans("工作经历删除成功"));

    }

    /**
     *
     *
     * 更新头像
     * @param Request $request
     * @return JsonResponse
     * @throws BusinessException
     */
    public function updateAvatar(Request $request): JsonResponse
    {
        $file = $request->file('image');
        if (!empty($file)) {
            $storage = Storage::disk();
            $uploadFile = $storage->put(SystemController::$dictionaries[1], $file);
            if (!$uploadFile) {
                self::error(trans("上传文件失败"));
                self::exception(ResponseCode::SERVICE_UNAVAILABLE, trans(''));
            }
        } else {
            self::error(trans("请选择文件"));
        }
        UserService::editPayProfile(auth('api')->id(), [
            'avatar_url' => $storage->url($uploadFile),
        ]);
        return self::success(trans("修改工作经历成功"),ResponseCode::OK,new UserInfo(User::query()->find(auth('api')->id())));
    }

    public function wxlogin(Request $request,UmengService $umengService){

        $input = $request->validate([
            'code' => 'required',
        ]);
        $post_data = [
            'code' => $input["code"],
        ];
        
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx468373cfe0e5a47f&secret=85f0fa177be1f31a556b7f10867e5fdc";
        $result = $this->get($url);
        $flag = json_decode($result, true);
        $access_token = $flag["access_token"];
        $data = json_encode($post_data);
        $res = $this->http_curl("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=".$access_token,$method = 'POST',$data,[]);
        if($res["errmsg"] == "ok" && $res["errcode"] == 0){
            $mobile = $res["phone_info"]["phoneNumber"];
        }else{
            return self::error(trans("手机号获取失败"));
        }
        $userInfo = User::query()->where('mobile',$mobile)->first();
        if (!$userInfo) {
            //账号不存在注册新用户
            UserService::pcreateUser(
                mobile: $mobile
            );
            $userInfo = User::query()->where('mobile', $mobile)->first();
        }else{
            // if(empty($userInfo->uuname)){
            //     //账号存在直接注册环信
            //     $username = 'user_uuid_'.$userInfo->id;
            //     //注册环信 获取用户uuid
            //     $EasemobService = new EasemobService;
            //     $res = $EasemobService->createUser($username,"123456",$username);
            //     User::query()->where("id",$userInfo->id)->update(["uuid"=>$res["uuid"],"uuname"=>$username]);
            // }
            $userInfo = User::query()->where('mobile', $mobile)->first();
        }
        $token = auth('api')->login($userInfo);
   
        //获取最后一次的token并加入黑名单
        $lastToken = Cache::get("userAppletToken:{$userInfo->id}");
        if ($lastToken) {
            try {
//                auth('api')->setToken($lastToken)->invalidate();
            } catch (JWTException $e) {
                //因为让一个过期的token再失效，会抛出异常，所以我们捕捉异常，不需要做任何处理
            }
        }
        $expiresIn = auth('api')->factory()->getTTL() * 60000;
        // 将用户token存入缓存
        Cache::set("userAppletToken:{$userInfo->id}", $token, $expiresIn);
        $userInfo->last_at = now();
        $userInfo->last_ip = $request->ip();
        $userInfo->save();
        // $hxdata = [
        //     "user_id"=>$userInfo->id,
        //     "uuid"=>$userInfo->uuid,
        //     "uuname"=>$userInfo->uuname,
        //     "uutoken"=>$EasemobService->hxtoken()
        // ];
        $imdata = [
            "user_id" => 'user_' . $userInfo->id,
            "user_name" => 'user_' . $userInfo->id,
            "user_token" => (new WechatService)->get_token('user_' . $userInfo->id)
        ];
        return self::success(trans("登录成功"), ResponseCode::OK, ['access_token' => $token,
            'token_type' => 'Bearer ',
            'userInfo' => $imdata,
            'expires_in' => $expiresIn]);

 
    }

    
     /**
     * @param string $url   请求地址
     * @param array $header 请求头
     * @param int $timeOut  请求时间
     * @return bool|string
     */
    public  function get(string $url, array $header = [], int $timeOut = 10)
    {
        return self::curlRequest($url, 'GET', [], '', $header, $timeOut);
    }


    /**
     * @param string $url   请求地址
     * @param string $method    请求方式
     * @param array $params     请求参数
     * @param string $paramsType    请求数据类型
     * @param array $header     请求头
     * @param int $timeOut      请求时间
     * @return bool|string
     */
    public function curlRequest(string $url, string $method = '', array $params = [], string $paramsType = '', array $header = [], int $timeOut)
    {
        $resHeader = [];
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);    // 地址
        curl_setopt($ch, CURLOPT_HEADER, 0);    // 请求头
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);    //获取的信息以文件流的形式放回， 而不是直接输出
        curl_setopt($ch, CURLINFO_HEADER_OUT, true);    // TRUE 时追踪句柄的请求字符串, 这个很关键，就是允许你查看请求header
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeOut);    // 告诉成功 PHP 从服务器接收缓冲完成前需要等待多长时间，如果目标是个巨大的文件，生成内容速度过慢或者链路速度过慢，这个参数就会很有用
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeOut);     //  告诉 PHP 在成功连接服务器前等待多久（连接成功之后就会开始缓冲输出），这个参数是为了应对目标服务器的过载，下线，或者崩溃等可能状况
        curl_setopt($ch, CURLOPT_FAILONERROR, false);  // PHP在发生错误(HTTP代码返回大于等于300)时，不显示,设置这个选项为一人非零值。默认行为是返回一个正常页，忽略代码。
        if (1 == strpos('$'.$url, "https://")) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }
        if ($method == 'POST') {
            curl_setopt($ch, CURLOPT_POST, true);
            if ($paramsType == 'JSON') {
                $resHeader[] = 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8';
                $resParams = json_encode($params);
            } else {
                $resParams = http_build_query($params);
            }
            curl_setopt($ch, CURLOPT_POSTFIELDS, $resParams);
        } else if ($method == 'PUT') {
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
        } else if ($method == 'DELETE') {
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
        }
        $resHeader = array_merge($resHeader, $header);
        if ($resHeader) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $resHeader);
        }
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
    }


      /**
    * 发送 post 请求 
    * @access protected
    * @return string
    */
    protected function http_curl($url, $method = 'POST', $data = array(), $header, $timeout = 10)
   {
       $curl = curl_init($url);
       $method = strtoupper($method);
       //请求方式啥
       curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
       //post请求
       if ($method == 'POST') curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
       //超时时间
       curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
       //设置header头
       // if ($header !== false) curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
       curl_setopt($curl, CURLOPT_HTTPHEADER, $header); 
       
       curl_setopt($curl, CURLOPT_FAILONERROR, false);
       //返回抓取数据
       curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
       //输出header头信息
       curl_setopt($curl, CURLOPT_HEADER, true);
       //TRUE 时追踪句柄的请求字符串，从 PHP 5.1.3 开始可用。这个很关键，就是允许你查看请求header
       curl_setopt($curl, CURLINFO_HEADER_OUT, true);


       //https请求
       if (1 == strpos("$" . $url, "https://")) {
           curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
           curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
       }
       $curlError = curl_error($curl);
     
       list($content, $status) = [curl_exec($curl), curl_getinfo($curl), curl_close($curl)];
       $status = $status;
       
       $headerStr = trim(substr($content, 0, $status['header_size']));
       $content = trim(substr($content, $status['header_size']));
       
        $cont = json_decode($content,true);
        
       //  $cont['headers'] =$headerStr;   //返回的头部信息去掉
        return $cont;

   }
}
